#ifndef APP_SERVER_H
#define APP_SERVER_H

#include "Socket.h"
#include "threading.h"

class Server : public Socket
{
public:
    enum class ServerEnum {
        FORK,
        THREAD,
        SELECT,
        POLL,
        EPOLL
    };
    struct Client {
        int fd;
        struct sockaddr_in addr;
        socklen_t addrlen;
    };
    class ServerListener {
    public:
        /* 1. 多进程/多线程 处理程序 */
        virtual void callback(Server* server, Server::Client* client) = 0;
        /* 2. select 客户端建立连接后执行 返回false主动断开连接 */
        virtual bool connect(Server* server, Server::Client* client) = 0;
        /* 3. select 接收到客户端发送的数据执行 返回false主动断开连接 */
        virtual bool recv(Server* server, Server::Client* client, char* buffer, int len) = 0;
    };
    Server(/* args */);
    Server(const int port, const char *ip, int listen);
    ~Server();
    void setMaxListenCounter(int backlog);
    int getMaxListenCounter(int backlog);
    void setListener(ServerListener* serverListener);
    int startListen(ServerEnum serverEnum);
private:
    class ServerThread : public Thread {
    private:
        void destory() {
            if (mClient != nullptr) {
                delete mClient;
                mClient = nullptr;
            }
        }
    public:
        ServerThread() {
        }
        ~ServerThread() {
            destory();
        }
        void init(Server* server, Server::Client* client) {
            mServer = server;
            mClient = client;
        }
        void threadMain() {
            if (mServer != nullptr && mServer->mServerListener != nullptr && mClient != nullptr) {
                mServer->mServerListener->callback(mServer, mClient);
                close(mClient->fd);
            }
            this->~ServerThread();
        }
    private:
        Server* mServer = nullptr;
        Server::Client* mClient = nullptr;
    };
    const int mPort;
    const char *mIp;
    int mListenCounter;
    ServerListener* mServerListener = nullptr;
};

#endif /* APP_SERVER_H */
